# -*- coding: utf-8 -*-
import scrapy
import re
import datetime
from scrapy.http.request import Request
from scrapy.loader import ItemLoader
from urllib import parse
from ..items import ArticleItem, ArticleItemLoader
from ..utils.common import get_md5


class JobboleSpider(scrapy.Spider):
    name = 'jobbole'
    allowed_domains = ['blog.jobbole.com']
    # 放置爬取的URL列表
    # start_urls = ['http://blog.jobbole.com/']
    start_urls = ['http://blog.jobbole.com/all-posts/']
    # scrapy的下载器会根据Request下载所有的东西，包括url、encoding、body
    # 下载完成之后进入parse里，所以这里是写自定义逻辑的地方，如何将爬取的数据保存下来
    def parse(self, response):
        """
        1、获取文章列表页中的文章url并交给解析函数进行具体字段的解析，也就是下面这块逻辑
        2、当前列表页获取完毕，将获取下一页的url并交给scrapy进行下载，继续解析具体字段
        获取下一页的url并交给scrapy进行下载
        """
        # 解析列表页中所有文字url
        post_nodes = response.css("#archive .post.floated-thumb .post-thumb a")
        for post_node in post_nodes:
            # 如果当前爬取的网页是相对路径的格式，那么就需要这样处理：response.url+post_url
            # 因为scrapy底层使用的是，他是一个异步IO的库，callback是调用了twisted的异步机制
            image_url = post_node.css("img::attr(src)").extract_first("")
            post_url = post_node.css("::attr(href)").extract_first("")
            # image_url单独出来，目的是为了兼容使用cdn和使用本地存储两种方式
            yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url": image_url},
                          callback=self.parse_detail)

        # 提取下一页并交给scrapy进行下载
        next_url = response.css(".next.page-numbers::attr(href)").extract_first("")
        if next_url:
            yield Request(url=parse.urljoin(response.url, next_url),callback=self.parse)

    def parse_detail(self, response):
        # 实例化一个item
        article_item = ArticleItem()
        # xpath直接通过浏览器查找并复制来的省力
        # ================爬取正文内容==================
        # connect = response.xpath("//div[@class='entry']").extract_first()
        # pattern = re.compile(r'<[^>]+>', re.S)
        # result = pattern.sub('', connect)
        # print("爬取的结果为{}".format(result))
        # =================爬取图片======================
        from_image_url = response.meta.get("front_image_url", "")
        # 通过itemloader加载item，后期可通过配置文件动态配置，或通过数据库动态配置
        item_loader = ArticleItemLoader(item=ArticleItem(), response=response)
        item_loader.add_css("title", ".entry-header h1::text")
        item_loader.add_value("url", response.url)
        item_loader.add_value("url_object_id", get_md5(response.url))
        item_loader.add_css("create_time", ".entry-meta-hide-on-mobile::text")
        item_loader.add_value("from_image_url", [from_image_url])
        item_loader.add_css("praise_num", ".vote-post-up h10::text")
        item_loader.add_css("collect_num", ".bookmark-btn::text")
        item_loader.add_css("comment_num", "a[href='#article-comment'] span::text")
        item_loader.add_xpath("tags", "//p[@class='entry-meta-hide-on-mobile']/a/text()")
        article_item = item_loader.load_item()
        # 会路由到pipelines，需要修改setting的ITEM_PIPELINES
        yield article_item

    pass
